package com.nbsaas.boot;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 正则表达式提取器
 * 支持多种正则配置，完整匹配检查和重试机制
 */
public class RegexExtractor {
    
    /**
     * 正则配置类
     */
    public static class RegexConfig {
        private final String name;
        private final String pattern;
        private final String fieldName;
        private final int groupIndex;
        private final int priority; // 优先级，数字越小优先级越高
        
        public RegexConfig(String name, String pattern, String fieldName, int groupIndex, int priority) {
            this.name = name;
            this.pattern = pattern;
            this.fieldName = fieldName;
            this.groupIndex = groupIndex;
            this.priority = priority;
        }
        
        public RegexConfig(String name, String pattern, String fieldName, int groupIndex) {
            this(name, pattern, fieldName, groupIndex, 0);
        }
        
        public String getName() { return name; }
        public String getPattern() { return pattern; }
        public String getFieldName() { return fieldName; }
        public int getGroupIndex() { return groupIndex; }
        public int getPriority() { return priority; }
    }
    
    /**
     * 提取结果类
     */
    public static class ExtractionResult {
        private final boolean isComplete;
        private final CallInfo extractedInfo;
        private final List<String> matchedPatterns;
        private final int totalPatterns;
        private final double successRate;
        
        public ExtractionResult(boolean isComplete, CallInfo extractedInfo, List<String> matchedPatterns, int totalPatterns) {
            this.isComplete = isComplete;
            this.extractedInfo = extractedInfo;
            this.matchedPatterns = matchedPatterns;
            this.totalPatterns = totalPatterns;
            this.successRate = totalPatterns > 0 ? (double) matchedPatterns.size() / totalPatterns : 0.0;
        }
        
        public boolean isComplete() { return isComplete; }
        public CallInfo getExtractedInfo() { return extractedInfo; }
        public List<String> getMatchedPatterns() { return matchedPatterns; }
        public int getTotalPatterns() { return totalPatterns; }
        public double getSuccessRate() { return successRate; }
    }
    
    // 定义多种正则配置，按优先级排序
    private static final List<RegexConfig> REGEX_CONFIGS = List.of(
        // 高优先级配置 (优先级 0-9)
        new RegexConfig("标准手机号", "^1\\d{10}$", "phone", 0, 0),
        new RegexConfig("标准时间", "^(\\d{2}:\\d{2})去电$", "callTime", 1, 0),
        new RegexConfig("标准时长", "^(\\d+)秒钟$", "duration", 1, 0),
        
        // 中优先级配置 (优先级 10-19)
        new RegexConfig("宽松手机号", "1\\d{10}", "phone", 0, 10),
        new RegexConfig("宽松时间", "(\\d{2}:\\d{2})", "callTime", 1, 10),
        new RegexConfig("宽松时长", "(\\d+)[秒分]", "duration", 1, 10),
        
        // 低优先级配置 (优先级 20-29)
        new RegexConfig("更宽松手机号", "\\d{11}", "phone", 0, 20),
        new RegexConfig("更宽松时间", "(\\d{1,2}:\\d{2})", "callTime", 1, 20),
        new RegexConfig("更宽松时长", "(\\d+)[秒分]钟?", "duration", 1, 20),
        
        // 特殊格式配置 (优先级 30-39)
        new RegexConfig("特殊手机号", "1[3-9]\\d{9}", "phone", 0, 30),
        new RegexConfig("特殊时间", "(\\d{2}:\\d{2})[去来]电", "callTime", 1, 30),
        new RegexConfig("特殊时长", "(\\d+)[秒分]钟?$", "duration", 1, 30),
        
        // 新增：专门处理"通话时长: X 秒"格式 (优先级 40-49)
        new RegexConfig("通话时长格式", "通话时长:\\s*(\\d+)\\s*秒", "duration", 1, 40),
        new RegexConfig("时长数字格式", "(\\d+)\\s*秒", "duration", 1, 41)
    );
    
    /**
     * 使用正则配置提取信息
     * @param words OCR识别的文字列表
     * @return 提取结果
     */
    public ExtractionResult extractWithConfigs(List<String> words) {
        CallInfo extractedInfo = new CallInfo();
        List<String> matchedPatterns = new ArrayList<>();
        
        // 按优先级排序配置
        List<RegexConfig> sortedConfigs = new ArrayList<>(REGEX_CONFIGS);
        sortedConfigs.sort((a, b) -> Integer.compare(a.getPriority(), b.getPriority()));
        
        // 尝试所有配置
        for (RegexConfig config : sortedConfigs) {
            boolean matched = tryExtractWithConfig(words, config, extractedInfo);
            if (matched) {
                matchedPatterns.add(config.getName());
            }
        }
        
        // 检查是否完整提取
        boolean isComplete = isCompleteExtraction(extractedInfo);
        
        return new ExtractionResult(isComplete, extractedInfo, matchedPatterns, sortedConfigs.size());
    }
    
    /**
     * 使用单个配置尝试提取
     * @param words OCR识别的文字列表
     * @param config 正则配置
     * @param extractedInfo 提取结果对象
     * @return 是否匹配成功
     */
    private boolean tryExtractWithConfig(List<String> words, RegexConfig config, CallInfo extractedInfo) {
        try {
            Pattern pattern = Pattern.compile(config.getPattern());
            
            for (String word : words) {
                Matcher matcher = pattern.matcher(word);
                if (matcher.find()) {
                    String value = matcher.group(config.getGroupIndex());
                    
                    // 根据字段名设置对应的值
                    switch (config.getFieldName()) {
                        case "phone":
                            if (extractedInfo.phone == null) {
                                extractedInfo.phone = value;
                            }
                            break;
                        case "callTime":
                            if (extractedInfo.callTime == null) {
                                extractedInfo.callTime = value;
                            }
                            break;
                        case "duration":
                            if (extractedInfo.duration == null) {
                                // 确保时长格式为数字
                                extractedInfo.duration = normalizeDuration(value);
                            }
                            break;
                    }
                    
                    return true;
                }
            }
        } catch (Exception e) {
            System.err.println("正则匹配失败 - 配置: " + config.getName() + ", 错误: " + e.getMessage());
        }
        
        return false;
    }
    
    /**
     * 检查是否完整提取了所有字段
     * @param extractedInfo 提取的信息
     * @return 是否完整
     */
    private boolean isCompleteExtraction(CallInfo extractedInfo) {
        return extractedInfo.phone != null && 
               extractedInfo.callTime != null && 
               extractedInfo.duration != null;
    }
    
    /**
     * 获取所有正则配置
     * @return 正则配置列表
     */
    public static List<RegexConfig> getRegexConfigs() {
        return new ArrayList<>(REGEX_CONFIGS);
    }
    
    /**
     * 添加自定义正则配置
     * @param config 正则配置
     */
    public static void addRegexConfig(RegexConfig config) {
        // 注意：这里需要修改为可变的List实现
        // 为了简化，这里只是示例方法
        System.out.println("添加正则配置: " + config.getName());
    }
    
    /**
     * 标准化时长格式，确保为整型数字格式
     * @param durationStr 原始时长字符串
     * @return 标准化后的时长整型值
     */
    private static Integer normalizeDuration(String durationStr) {
        if (durationStr == null || durationStr.trim().isEmpty()) {
            return null;
        }
        
        try {
            // 移除所有非数字字符，只保留数字
            String numbersOnly = durationStr.replaceAll("[^0-9]", "");
            
            if (numbersOnly.isEmpty()) {
                return null;
            }
            
            // 转换为整数，确保格式正确
            return Integer.parseInt(numbersOnly);
            
        } catch (NumberFormatException e) {
            System.err.println("时长格式转换失败: " + durationStr);
            return null;
        }
    }

    /**
     * 获取配置统计信息
     * @return 配置统计信息
     */
    public static String getConfigStats() {
        StringBuilder stats = new StringBuilder();
        stats.append("正则配置统计:\n");
        stats.append("总配置数量: ").append(REGEX_CONFIGS.size()).append("\n");
        
        // 按字段分组统计
        long phoneConfigs = REGEX_CONFIGS.stream().filter(c -> "phone".equals(c.getFieldName())).count();
        long timeConfigs = REGEX_CONFIGS.stream().filter(c -> "callTime".equals(c.getFieldName())).count();
        long durationConfigs = REGEX_CONFIGS.stream().filter(c -> "duration".equals(c.getFieldName())).count();
        
        stats.append("手机号配置: ").append(phoneConfigs).append(" 个\n");
        stats.append("时间配置: ").append(timeConfigs).append(" 个\n");
        stats.append("时长配置: ").append(durationConfigs).append(" 个\n");
        
        return stats.toString();
    }
} 